package com.empsys.exceptionhandler;

import com.empsys.config.exception.MyException;
import com.empsys.pojo.Result;
import org.springframework.dao.DataAccessException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @author wzm
 * @create 2023-12-15 9:30
 * project_name:web2310
 * @Description
 */
//全局异常处理器  异常逐层上抛 Controller如果不处理抛给异常处理器
@RestControllerAdvice  //@ResponseBody+ControllerAdvice
public class GlobalExceptionHanlder {


    //指定异常处理器的方法 用处理发生异常时的返回结果Restult

    /**
     * 所有异常都会触发此方法 但是如果有具体的异常处理Handler
     * 具体异常处理器优先级会更高
     * 如:发生了NullPointerException异常
     * 此时触发的应该是具体定义了的空指针异常处理器而不是Exception处理器
     * @return
     */
    @ExceptionHandler(Exception.class)     //标记方法为异常处理器 如果不指定 默认是Exception
    public Result handler(Exception ex){ //一旦有异常 触发此方法后 spring会将异常对象封装到形参中
        ex.printStackTrace();//打印异常的堆栈信息
        return Result.error("出现错误，请联系管理员");
    }


    //捕获具体的错误  具体的提示
    //处理除数为0的特定的异常
    @ExceptionHandler(ArithmeticException.class)
    public Result handler(ArithmeticException ex){
        ex.printStackTrace();
        return Result.error("对不起，除数不能为0,请修改");
    }


    /*
    * 特殊：
    * Spring为dao层为了统一处理，屏蔽了与特定技术相关的异常 如：用了三方的DbUtils  mybatis  hiberbate等
    * 此时如果dao出现问题即使向抛 控制台打印的异常，都无法异常处理器的特定异常匹配，
    * 因为spring设定dao层抛出的异常统一为：org.springframework.dao.DataAccessException的子类
    * */

    //处理唯一约束插入重复值异常
    @ExceptionHandler(DataAccessException.class)
    public Result handler(SQLIntegrityConstraintViolationException ex){
        ex.printStackTrace();
        String message = ex.getMessage();
        System.out.println("message = " + message);//message = Duplicate entry '人事部' for key 'dept.name'

        if(message.contains("Duplicate entry")){//发生了唯一约束重复插入
            String[] s = message.split(" ");//按空格截取字符串
            return Result.error("对不起，您输入的["+ s[2] + "]已经存在，请勿重复添加哟！！");
        }else {
            return Result.error("发生了未知SQL异常，小哥正在努力恢复...");
        }
    }


    //自定异常，通常情况下 除了系统抛出的异常外，在我们进行业务功能书写中还会出现根据判断提示一个属于自己的异常 也可以定义异常 被处理器处理

    @ExceptionHandler(MyException.class)
    public Result handler(MyException ex){
        ex.printStackTrace();
        //响应自定义异常信息
        return Result.error(ex.getMessage());
    }

}
